<template>
  <div class="market-heatmap bg-white dark:bg-gray-700 rounded-lg shadow p-4">
    <h2 class="text-lg font-semibold mb-4 dark:text-gray-200">市场热力图</h2>
    
    <div v-if="loading" class="flex justify-center items-center h-64">
      <LoadingSpinner />
    </div>
    
    <div v-else-if="error" class="text-center text-red-600 dark:text-red-400">
      {{ error }}
    </div>
    
    <div v-else>
      <!-- 热力图控制 -->
      <div class="flex justify-between items-center mb-4">
        <div class="flex space-x-2">
          <button 
            v-for="option in viewOptions" 
            :key="option.value"
            @click="currentView = option.value"
            class="px-3 py-1 text-sm rounded transition-colors"
            :class="currentView === option.value ? 
              'bg-blue-600 text-white' : 
              'bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-gray-500'"
          >
            {{ option.label }}
          </button>
        </div>
        
        <div class="flex items-center space-x-2">
          <span class="text-sm text-gray-600 dark:text-gray-400">时间范围:</span>
          <select 
            v-model="timeRange"
            class="text-sm px-2 py-1 border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
          >
            <option value="1d">今日</option>
            <option value="5d">5日</option>
            <option value="1m">1个月</option>
            <option value="3m">3个月</option>
            <option value="6m">6个月</option>
            <option value="1y">1年</option>
          </select>
        </div>
      </div>
      
      <!-- 热力图图例 -->
      <div class="flex justify-center items-center mb-4">
        <div class="flex items-center">
          <div class="w-4 h-4 bg-red-700 rounded"></div>
          <span class="text-xs ml-1 mr-2 text-gray-600 dark:text-gray-400">-5%+</span>
          
          <div class="w-4 h-4 bg-red-500 rounded"></div>
          <span class="text-xs ml-1 mr-2 text-gray-600 dark:text-gray-400">-2% ~ -5%</span>
          
          <div class="w-4 h-4 bg-red-300 rounded"></div>
          <span class="text-xs ml-1 mr-2 text-gray-600 dark:text-gray-400">0% ~ -2%</span>
          
          <div class="w-4 h-4 bg-green-300 rounded"></div>
          <span class="text-xs ml-1 mr-2 text-gray-600 dark:text-gray-400">0% ~ 2%</span>
          
          <div class="w-4 h-4 bg-green-500 rounded"></div>
          <span class="text-xs ml-1 mr-2 text-gray-600 dark:text-gray-400">2% ~ 5%</span>
          
          <div class="w-4 h-4 bg-green-700 rounded"></div>
          <span class="text-xs ml-1 text-gray-600 dark:text-gray-400">5%+</span>
        </div>
      </div>
      
      <!-- 行业热力图 -->
      <div v-if="currentView === 'sector'" class="mb-4">
        <div class="grid grid-cols-4 gap-2">
          <div 
            v-for="sector in sectorData" 
            :key="sector.name"
            class="p-3 rounded cursor-pointer hover:opacity-90 transition-opacity"
            :class="getHeatmapColor(sector.change)"
            @click="selectSector(sector.name)"
          >
            <div class="font-medium text-white">{{ sector.name }}</div>
            <div class="text-sm text-white opacity-90">{{ formatChange(sector.change) }}</div>
          </div>
        </div>
      </div>
      
      <!-- 个股热力图 -->
      <div v-else-if="currentView === 'stocks' && selectedSector">
        <div class="mb-3">
          <button 
            @click="selectedSector = null"
            class="text-sm text-blue-600 dark:text-blue-400 hover:underline"
          >
            &larr; 返回行业视图
          </button>
          <h3 class="text-md font-medium dark:text-gray-200">{{ selectedSector }} - 个股表现</h3>
        </div>
        
        <div class="grid grid-cols-6 gap-1">
          <div 
            v-for="stock in getStocksForSector(selectedSector)" 
            :key="stock.code"
            class="p-2 rounded cursor-pointer hover:opacity-90 transition-opacity"
            :class="getHeatmapColor(stock.change)"
          >
            <div class="text-xs font-medium text-white">{{ stock.name }}</div>
            <div class="text-xs text-white opacity-90">{{ stock.code }}</div>
            <div class="text-xs text-white">{{ formatChange(stock.change) }}</div>
          </div>
        </div>
      </div>
      
      <!-- 市值热力图 -->
      <div v-else-if="currentView === 'marketcap'">
        <div ref="marketCapHeatmap" class="h-96"></div>
      </div>
      
      <!-- 成交量热力图 -->
      <div v-else-if="currentView === 'volume'">
        <div ref="volumeHeatmap" class="h-96"></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import { useAITradeStore } from '../store'
import errorHandler, { ErrorType, ErrorSeverity } from '../utils/error-handler'
import LoadingSpinner from './global/LoadingSpinner.vue'
import * as echarts from 'echarts'

const store = useAITradeStore()
const loading = ref(true)
const error = ref(null)

// 视图选项
const viewOptions = [
  { label: '行业', value: 'sector' },
  { label: '个股', value: 'stocks' },
  { label: '市值', value: 'marketcap' },
  { label: '成交量', value: 'volume' }
]

// 当前视图和时间范围
const currentView = ref('sector')
const timeRange = ref('1d')
const selectedSector = ref(null)

// 热力图数据
const sectorData = ref([])
const stocksData = ref([])

// 图表引用
const marketCapHeatmap = ref(null)
const volumeHeatmap = ref(null)
let marketCapChart = null
let volumeChart = null

// 获取热力图数据
async function fetchHeatmapData() {
  try {
    loading.value = true
    error.value = null
    
    const data = await store.getMarketHeatmapData(timeRange.value)
    if (data) {
      sectorData.value = data.sectors
      stocksData.value = data.stocks
      
      // 更新图表
      if (currentView.value === 'marketcap' && marketCapHeatmap.value) {
        renderMarketCapHeatmap()
      }
      
      if (currentView.value === 'volume' && volumeHeatmap.value) {
        renderVolumeHeatmap()
      }
    }
  } catch (err) {
    error.value = '获取热力图数据失败'
    errorHandler.handleError(err, ErrorType.API, ErrorSeverity.WARNING)
  } finally {
    loading.value = false
  }
}

// 选择行业
function selectSector(sectorName) {
  selectedSector.value = sectorName
  currentView.value = 'stocks'
}

// 获取行业内的股票
function getStocksForSector(sectorName) {
  return stocksData.value.filter(stock => stock.sector === sectorName)
}

// 渲染市值热力图
function renderMarketCapHeatmap() {
  if (!marketCapChart) {
    marketCapChart = echarts.init(marketCapHeatmap.value)
  }
  
  const data = stocksData.value.map(stock => ({
    name: stock.name,
    value: stock.marketCap,
    change: stock.change
  }))
  
  const option = {
    tooltip: {
      formatter: function(params) {
        return `${params.name}<br/>市值: ${formatPrice(params.value)}<br/>涨跌幅: ${formatChange(params.data.change)}`
      }
    },
    series: [{
      type: 'treemap',
      data: data,
      label: {
        show: true,
        formatter: '{b}',
        fontSize: 12
      },
      itemStyle: {
        color: function(params) {
          return getEChartsColor(params.data.change)
        }
      }
    }]
  }
  
  marketCapChart.setOption(option)
}

// 渲染成交量热力图
function renderVolumeHeatmap() {
  if (!volumeChart) {
    volumeChart = echarts.init(volumeHeatmap.value)
  }
  
  const data = stocksData.value.map(stock => ({
    name: stock.name,
    value: stock.volume,
    change: stock.change
  }))
  
  const option = {
    tooltip: {
      formatter: function(params) {
        return `${params.name}<br/>成交量: ${formatVolume(params.value)}<br/>涨跌幅: ${formatChange(params.data.change)}`
      }
    },
    series: [{
      type: 'treemap',
      data: data,
      label: {
        show: true,
        formatter: '{b}',
        fontSize: 12
      },
      itemStyle: {
        color: function(params) {
          return getEChartsColor(params.data.change)
        }
      }
    }]
  }
  
  volumeChart.setOption(option)
}

// 初始化
onMounted(async () => {
  await fetchHeatmapData()
  
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)
})

// 处理窗口大小变化
function handleResize() {
  if (marketCapChart) {
    marketCapChart.resize()
  }
  
  if (volumeChart) {
    volumeChart.resize()
  }
}

// 辅助函数
function getHeatmapColor(change) {
  if (change <= -5) return 'bg-red-700'
  if (change <= -2) return 'bg-red-500'
  if (change < 0) return 'bg-red-300'
  if (change < 2) return 'bg-green-300'
  if (change < 5) return 'bg-green-500'
  return 'bg-green-700'
}

function getEChartsColor(change) {
  if (change <= -5) return '#b91c1c' // red-700
  if (change <= -2) return '#ef4444' // red-500
  if (change < 0) return '#fca5a5' // red-300
  if (change < 2) return '#86efac' // green-300
  if (change < 5) return '#22c55e' // green-500
  return '#15803d' // green-700
}

function formatChange(change) {
  return `${change > 0 ? '+' : ''}${change.toFixed(2)}%`
}

function formatPrice(value) {
  return new Intl.NumberFormat('zh-CN', {
    style: 'currency',
    currency: 'CNY',
    notation: 'compact',
    compactDisplay: 'short'
  }).format(value)
}

function formatVolume(value) {
  return new Intl.NumberFormat('zh-CN', {
    notation: 'compact',
    compactDisplay: 'short'
  }).format(value)
}

// 监听数据变化
watch([currentView, timeRange], async () => {
  if (currentView.value !== 'stocks') {
    selectedSector.value = null
  }
  
  await fetchHeatmapData()
})
</script>